package com.feige.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.feige.constant.Constants;
import com.feige.entity.SecurityUser;
import com.feige.pojo.User;
import com.feige.dao.UserMapper;
import com.feige.pojo.UserRole;
import com.feige.pojo.dto.UserDto;
import com.feige.pojo.dto.UserQueryDto;
import com.feige.pojo.vo.BaseDeptVo;
import com.feige.service.DeptService;
import com.feige.service.UserRoleService;
import com.feige.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.feige.utils.common.Admin;
import com.feige.utils.common.MD5;
import com.feige.utils.exception.CustomException;
import com.feige.utils.http.ServletUtils;
import com.feige.utils.jwt.JwtUtils;
import com.feige.utils.redis.RedisUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.feige.utils.string.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author feige
 * @since 2020-07-20
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Resource
    private UserRoleService userRoleService;

    @Resource
    private DeptService deptService;

    @Resource
    private RedisUtils redisUtils;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveUser(UserDto userDto) {
        User user = new User();
        BeanUtils.copyProperties(userDto,user);
        user.setPassword(MD5.encrypt(user.getPassword()));
        boolean save = save(user);
        boolean assignRoles = true;
        if (!StringUtils.isEmpty(userDto.getRoleIds())){
            assignRoles = userRoleService.AssignRoles(user.getId(), userDto.getRoleIds());
        }
        return save && assignRoles;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateUser(UserDto userDto) {
        User user = new User();
        BeanUtils.copyProperties(userDto,user);
        if (!StringUtils.isEmpty(user.getPassword())){
            String encrypt = MD5.encrypt(user.getPassword());
            user.setPassword(encrypt);
        }else {
            user.setPassword(null);
        }
        if (!StringUtils.isEmpty(userDto.getRoleIds())){
            QueryWrapper<UserRole> wrapper = new QueryWrapper<>();
            wrapper.eq("user_id",user.getId());
            boolean remove = userRoleService.remove(wrapper);
            if (!remove){
                return false;
            }
        }
        boolean update = updateById(user);
        boolean assignRoles = true;
        if (!StringUtils.isEmpty(userDto.getRoleIds())){
            assignRoles = userRoleService.AssignRoles(user.getId(), userDto.getRoleIds());
        }
        return update && assignRoles;
    }

    @Override
    public IPage<User> listByUserQueryDto(UserQueryDto userQueryDto) {
        Page<User> pageParam = new Page<>(userQueryDto.getPageNum(), userQueryDto.getPageSize());
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        if(!org.springframework.util.StringUtils.isEmpty(userQueryDto.getNum())) {
            wrapper.like("num", userQueryDto.getNum());
        }
        if(!org.springframework.util.StringUtils.isEmpty(userQueryDto.getUsername())) {
            wrapper.like("username", userQueryDto.getUsername());
        }
        if (!org.springframework.util.StringUtils.isEmpty(userQueryDto.getSex())){
            wrapper.eq("sex", userQueryDto.getSex());
        }
        if (!org.springframework.util.StringUtils.isEmpty(userQueryDto.getNickname())){
            wrapper.like("nickname", userQueryDto.getNickname());
        }
        if (!org.springframework.util.StringUtils.isEmpty(userQueryDto.getPhoneNumber())){
            wrapper.like("phone_number", userQueryDto.getPhoneNumber());
        }
        if (!org.springframework.util.StringUtils.isEmpty(userQueryDto.getEmail())){
            wrapper.like("email", userQueryDto.getEmail());
        }
        if (!org.springframework.util.StringUtils.isEmpty(userQueryDto.getStatus())){
            wrapper.eq("status", userQueryDto.getStatus());
        }
        if (!org.springframework.util.StringUtils.isEmpty(userQueryDto.getBeginTime())){
            wrapper.ge("gmt_create", userQueryDto.getBeginTime());
        }
        if (!org.springframework.util.StringUtils.isEmpty(userQueryDto.getEndTime())){
            wrapper.le("gmt_create", userQueryDto.getEndTime());
        }
        HttpServletRequest req = ServletUtils.getRequest();
        String token = req.getHeader(Constants.TOKEN_KEY);
        String num = JwtUtils.getNumFromToken(token);
        List<Long> longs;
        if (Admin.isAdmin(num)){
            if (!org.springframework.util.StringUtils.isEmpty(userQueryDto.getDeptId())){
                //查询部门下的所有子部门的ID
                longs = deptService.queryDeptIds(userQueryDto.getDeptId());
                longs.add(userQueryDto.getDeptId());
                wrapper.in("dept_id",longs);
            }
        }else {
            String key = JwtUtils.getUsernameAndNumFromToken(token);
            SecurityUser securityUser = (SecurityUser) redisUtils.get(Constants.LOGIN_USER_KEY + key);
            if (StringUtils.isNotNull(securityUser)) {
                String manageDeptIds = securityUser.getCurrentUser().getManageDeptIds();
                if (!StringUtils.isEmpty(manageDeptIds)) {
                    String[] split = manageDeptIds.split(",");
                    Set<Long> set = Arrays.stream(split).map(Long::parseLong).collect(Collectors.toSet());
                    if (!org.springframework.util.StringUtils.isEmpty(userQueryDto.getDeptId())){
                        longs = deptService.queryDeptIds(userQueryDto.getDeptId());
                        //求交集
                        set.retainAll(longs);
                        set.add(userQueryDto.getDeptId());
                    }
                    wrapper.in("dept_id",set);
                }else {
                    throw new  CustomException("您没有管理的部门，查询失败！", 500);
                }
            }else {
                throw new  CustomException("缓存中查询不到您的登录信息，请重新登录！", 500);
            }
        }
        return this.page(pageParam, wrapper);
    }

}
